/*Channel模块*/
#pragma once
#include"Common.hpp"
class Poller;
class EventLoop;
class Channel
{
private:
    int _fd;
    EventLoop *_loop;
    uint32_t _events;  // 当前需要监控的事件
    uint32_t _revents; // 当前连接触发的事件
    using EventCallback = std::function<void()>;
    EventCallback _read_callback;  // 可读事件被触发的回调函数
    EventCallback _write_callback; // 可写事件被触发的回调函数
    EventCallback _error_callback; // 错误事件被触发的回调函数
    EventCallback _close_callback; // 连接断开事件被触发的回调函数
    EventCallback _event_callback; // 任意事件被触发的回调函数
public:
    Channel(EventLoop *loop, int fd)
        : _fd(fd),
          _events(0),
          _revents(0),
          _loop(loop)
    {
    }
    // 移除监控
    void Remove();
    void Update();
    int Fd()
    {
        return _fd;
    }
    // 获取想要监控的事件
    uint32_t Events()
    {
        return _events;
    }
    void SetREvents(uint32_t revents)
    {
        _revents = revents;
    } // 设置实际就绪的事件
    void SetReadCallback(const EventCallback &cb)
    {
        _read_callback = cb;
    }
    void SetWriteCallback(const EventCallback &cb)
    {
        _write_callback = cb;
    }
    void SetErrorCallback(const EventCallback &cb)
    {
        _error_callback = cb;
    }
    void SetCloseCallback(const EventCallback &cb)
    {
        _close_callback = cb;
    }
    void SetEventCallback(const EventCallback &cb)
    {
        _event_callback = cb;
    }
    // 当前是否监控了可读
    bool ReadEnable()
    {
        return (_events & EPOLLIN);
    }
    // 当前是否监控了可写
    bool WritEnable()
    {
        return (_events & EPOLLOUT);
    }
    // 启动读事件监控
    void OpenReadEventMonitoring()
    {
        _events |= EPOLLIN;
        Update();
    }
    // 启动写事件监控
    void OpenWriteEventMonitoring()
    {
        _events |= EPOLLOUT;
        Update();
    }
    // 关闭读事件监控
    void CloseReadEventMonitoring()
    {
        _events &= (~EPOLLIN);
        Update();
    }
    // 关闭写事件监控
    void CloseWriteEventMonitoring()
    {
        _events &= (~EPOLLOUT);
        Update();
    }
    // 关闭所有事件监控
    void CloseAllEventMonitoring()
    {
        _events = 0;
        Update();
    }
    // 事件处理，⼀旦连接触发了事件，就调⽤这个函数，根据回调的设置来处理
    void HandleEvent()
    {
       
        if ((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI))
        {
            // 都看作读事件就绪!调用读回调函数处理
            if (_read_callback)
            {
                LOG(DEBUG, "描述符 %d 触发读事件,正在执行对应回调函数!\n", _fd);
                _read_callback();
            }
        }

        if (_revents & EPOLLOUT)
        {
            if (_write_callback)
            {
                LOG(DEBUG, "描述符 %d 触发写事件,正在执行对应回调函数!\n", _fd);
                _write_callback();
            }
        }
        else if (_revents & EPOLLERR)
        {
            if (_error_callback)
            {
                LOG(DEBUG, "描述符 %d 触发异常事件,正在执行对应回调函数!\n", _fd);
                _error_callback();
            }
        }
        else if (_revents & EPOLLHUP)
        {
            if (_close_callback)
            {
                LOG(DEBUG, "描述符 %d 触发连接关闭事件,正在执行对应回调函数!\n", _fd);
                _close_callback();
            }
        }
        if (_event_callback)
        {
            LOG(DEBUG, "描述符 %d 触发任意事件,正在执行对应回调函数!\n", _fd);
            _event_callback();
        }
    }

    
};